home *** CD-ROM | disk | FTP | other *** search
- Subject: v13i020: VN newsreader, 1/88 version, Part02/05
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Bob Mcqueer <amdahl!rtech!rtech!bobm@UUNET.UU.NET>
- Posting-number: Volume 13, Issue 20
- Archive-name: vn.jan.88/part02
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # server.doc
- # std.c
- # std.h
- # config_std.h
- export PATH; PATH=/bin:$PATH
- echo shar: extracting "'server.doc'" '(13304 characters)'
- if test -f 'server.doc'
- then
- echo shar: will not over-write existing file "'server.doc'"
- else
- cat << \SHAR_EOF > 'server.doc'
- vns_envir()
-
- called to allow server layer to set environment. Will be called
- before anything else. See the vn_env() routine if the server
- interface intends to use any environment variables.
-
- There are some procedure pointers in vn which may optionally
- be set by the server interface. By default, all of these are
- NULL:
-
- (*Massage)(hdr)
- ARTHEADER *hdr;
-
- Mail path massaging function. Allows server interface to
- interact with the user prior to editing the reply file
- on mail replies. See vns_aopen().
-
- (*Headedit)()
-
- If set, will be called instead of the default action when
- the user chooses the "toggle header flag" command. This
- is intended to allow the server interface to implement a
- user selection of which headers to display when reading
- an article. If this is set, note that the reader code will
- never rewind an article past the point set by vns_aopen().
-
- (*Postfunc)(hdr,fn)
- (*Mailfunc)(hdr,fn)
- ARTHEADER *hdr;
- char *fn;
-
- If set, these functions will be called for mail / post
- instead of spawning a command. They are intended for
- the instance in which these operations can be handled
- within the executable rather than forking another process.
- If forking another process has to be done, you might as
- well set up postcmd / mailcmd, and let vn do it. fn is
- the name of a file containing the user's article or mail
- reply.
-
- All of the procedures will be called with the user's terminal in
- raw mode and will be expected to leave it that way on return.
- If these routines need to control ioctl settings or send control
- sequences to the terminal, they should do so through the tty_set /
- term_set calls used by the rest of vn. These routines basically
- hide ioctl / termcap from everybody.
-
- vns_news (argc,argv,lfirst,unsub)
- int argc;
- char **argv;
- int *lfirst;
- int *unsub;
-
- called to let server layer process options and enter known newsgroups
- in vn structure. arguments are vn's command line. It calls four
- specific support routines:
-
- hashenter(group,highnum,lownum)
- char *group;
- int highnum, lownum;
-
- Enter information about a newsgroup. Group is newsgroup
- name, highnum the highest article number, lownum the lowest.
-
- NODE *
- hashfind(group)
- char *group;
-
- Return information on entered group. See node.h header
- file for structure and legal usage of its items by server
- interface routines. May be called by other vns_ rouines
- as well.
-
- fw_group(group,new,sub,read,look)
- char *group;
- int new, sub, read, look;
-
- prepare to enter display information for a new newsgroup.
- new is non-zero if this is to be considered a "new" newsgroup
- since the user's last session. sub is non-zero if user is
- to be considered "subscribed" to it. read is the initial
- "articles read" number for the newsgroup. look is non-zero
- if server interface intends to look for articles in this
- newsgroup. This parameter is open to interpretation, but
- should indicate that user's options mean group is to be looked
- at. This should NOT reflect the fact that no articles will
- be found because "read" is up to date. The parameter is only
- used for statistical collection, anyway.
-
- fw_art(anum,subj,lines,author)
- int anum;
- char *subj, *lines, *author;
-
- enter information for an article in the newsgroup last set
- with fw_group(). anum's should be entered in ascending
- sequence.
-
- fw_chg(new,sub,read,look)
- int new, sub, read, look;
-
- change the parameters for the current group. To allow the
- server interface to modify its setting for the group based
- on what it discovered while scanning the articles.
-
- fw_group() should be called once and only once for each group
- hashenter()'ed. The order of fw_group() calls determines the
- order of vn's display to the user. fw_group() calls may be made
- after all the hashenter() calls have been made, or they may be
- interleaved. If no fw_art() calls are made following a particular
- fw_group() call, no display page will be generated for that group.
- If vns_news does not stick to the rules regarding calls to fw_group,
- vn will exit with a fatal error message.
-
- Rationale for this is for the server layer to have no knowledge
- of device dependencies (the calls to fw_art will split up display
- pages), or any of the vn structures beyond the newsgroup information.
- And the newsgroup NODE structure has clearly documented pieces
- which are legal for the server to read or use, and others which are
- out-of-bounds. It isolates things fairly well.
-
- Note that vns_news hides all knowledge of the user's .newsrc file or
- similar concept, and all knowledge of where articles live and how
- they are administered. Error handling is brutally simple. If the
- server doesn't obey the rules, vn will exit with a fatal error message
- if it detects the fact.
-
- lfirst and unsub are returned to the caller based on the command
- line:
-
- lfirst - non-zero if vn is supposed to go directly to
- the newsgroup summary list on startup (-% option).
-
- unsub - set non-zero if unsubscribed newsgroups are to
- be updated on "write alls" (-U option).
-
- We COULD have vn look for these, and nail them down, but most command
- line options are things which make sense only to the server interface.
- Different environments may have different options which make sense.
- Might as well give the server interface control of the command line
- exclusively, and advise to consistently use -% and -U if possible.
-
- See below for some other support routines which might be useful for
- vns_news().
-
- In summary, what vns_news should do:
-
- Call hashenter() for all the legitimate newsgroups.
- After this, hashfind() may be called at any time to retrieve
- the information about a group.
-
- Call fw_group() once and only once for each group, in the
- order newsgroups should be displayed to the user. The order
- need bear no relation to the order of hashenter calls.
-
- After each fw_group call, shovel in article information with
- fw_art calls. Optionally call fw_chg() if anything ought to
- be changed from the original fw_group call.
-
- If there are fatal errors call printex() with an explanation.
-
- To produce non-fatal diagnostics / informational messages,
- call fgprintf(). If you absolutely want to produce the message,
- backgrounded or not, you CAN simply output to stderr / stdout,
- but think before doing it. It's obnoxious to have a
- backgrounded program stop on output before it's ready to
- interact with you.
-
- ISN'T THAT EASY?
-
- FILE *vns_aopen(art,hdr)
- int art;
- ARTHEADER *hdr;
-
- Returns an open file pointer to article text for vn's use, or
- NULL for failure. Fills in the ARTHEADER argument, containing
- information conceptually thought of as extracted from the "header"
- lines. File pointer should be positioned at the start of the
- bonafide article text, if headers are contained in the file. See
- head.h for the items to be filled in.
-
- If (*Massage)(), (*Postfunc)() or (*Mailfunc)() are defined, they
- will be called with this same ARTHEADER instance when they are
- called. vns_aopen may set up any arguments in the priv item
- for the convenience of these routines.
-
- CAUTION:
- hdr contains string pointers. vns_aopen must be sure to
- point to legitimate storage, not its stack. And it SHOULD
- NOT simply malloc() the strings every time without freeing
- the old ones somehow - this will lose storage every time the
- user reads a new article. You MAY NOT assume that the same
- instance of an ARTHEADER structure is passed to each
- vns_aopen() call, either. See str_tpool, and associated
- routines, below.
-
- vns_close(fp)
- FILE *fp;
-
- Called to close article opened with vns_open(). In many instances
- will simply be an fclose(). vn will NEVER have multiple articles
- open, so vns_aopen / vns_aclose may maintain static information if
- they like.
-
- vns_gset(grp)
- char *grp;
-
- Called as the user moves from page to page of the display. vns_aopen
- and vns_aclose calls will refer to this newsgroup. May do chdir()'s
- if it likes.
-
- vns_exit(stat)
- int stat;
-
- Called before exit to allow the server layer to clean up. Called
- on normal exit & from within printex() (ie. DON'T call printex in
- unconditionally in this routine)
-
- vns_write(news,count)
- NODE **news;
- int count;
-
- Called to do whatever is the conceptual equivalent of updating the
- user's .newsrc file. news is an array of newsgroup nodes in the
- order that fw_group was called, count is the length of the array.
- Vn may have modified the rdnum items & the FLG_SUB flag based on
- user interaction. User exit, "write" commands, and "subscription"
- commands will result in this call. vn will set a flag bit, FLG_ECHG,
- in the flag item of all newsgroups whose data it changed since last
- call. This bit may be used by vns_write to do selective updates, and
- will be cleared for all groups following return from vns_write().
-
- vns_asave(art,fp,count,name,mode)
- int art;
- FILE *fp;
- int count;
- char *name,*mode;
-
- Called to shovel an article out to an open file pointer. Intended
- to allow the server interface to implement any kind of massaging
- of the article text that is called for. count starts with 0, and
- counts the articles being written on this opening of the file.
- name is the file name, and mode is the mode it was opened with.
- This information is being passed in to allow implementation of
- selective copy of header lines, etc. based on the state of the
- file. Note that it WILL exist since it's already been opened. On
- count 0, this routine may be interested in whether it's empty or not.
- This routine WILL get called between vns_aopen and vns_aclose.
-
- char *Vns_version;
-
- The server layer must define this string. It should be a
- short string which describes the server type / version (something
- like "NNTP-1.0"). Will be printed as part of the vn version message.
-
- Some support routines:
-
- regex(), regcmp(), strtok() and strpbrk() are standard SYSV
- routines not normally available for BSD. vn uses them, so
- they are implemented in vn for those systems. Thus, they are
- available for use in the server interface. Be careful with
- strtok(), which retains context from call to call, if you are
- not familiar with its use. To free storage handed you by
- regcmp(), use regfree() instead of free().
-
- char *vn_env(var, def)
- char *var, *def;
-
- Use this in place of getenv() to be consistent with the rest of
- vn. This routine checks first for the variable prefixed with "VN"
- if it doesn't already begin with "VN". If neither the prefixed
- or unprefixed name exists, it returns the def argument. This allows
- consistent override of EDITOR with VNEDITOR, etc.
-
- printex(....)
-
- printf style argument list. Generates a fatal error and exits.
- No newline necessary in the message, and printex() adds the error
- number to its output automatically. printex() may be called from
- anywhere in the server interface to generate a fatal error, except
- from vns_exit().
-
- fgprintf(....)
-
- nonfatal diagnostic / informational message. printf style argument
- list. No extra formatting printed. Will only print if program is
- running in the foreground. fgprintf() should be called only from
- vns_envir() and vns_news(), as all the other routines come after
- user interaction has begun.
-
- char *
- str_store(s)
- char *s;
-
- Returns a pointer to a permanent copy of a string. DO NOT FREE THAT
- POINTER!! This routine is intended to save malloc() overhead, and
- returns pointers into larger buffer allocated with a single request.
-
- char *
- str_tstore(ptr,s)
- char *ptr;
- char *s;
-
- char *
- str_tpool(n)
- int n;
-
- char **
- str_taptr(ptr)
- char *ptr;
-
- str_tfree(ptr)
- char *ptr;
-
- Temporary string storage. str_tpool is called with the maximum
- number of strings to be allocated, and it returns a pointer to use
- with the other calls (ptr argument). str_tstore returns allocated
- copies of strings. str_taptr returns an address which may be treated
- as a string array containing the str_tstore allocated strings
- beginning with the NEXT str_tstore() call. May be called several
- times to get several array pointers. str_tfree() frees all the strings
- allocated on the given ptr returned from str_tpool, as well as the
- pool pointer itself. The returned addresses are no longer valid, nor
- is the pool pointer. Multiple pool pointers may be maintained.
- Pool pointer contents should not be touched by the caller. These
- routines are intended for the convenience of vns_aopen().
-
- HEADER FILES:
-
- server.h includes the header files used by vn which are intended to be known
- to server interface routines. The server interface routines may include
- system headers, this one, and their own headers. Among their own headers
- should be a config_*.h containing parameters which are likely to be changed
- from installation to installation, such as file paths. server.h contains
- node.h and head.h, defining the NODE and ARTHEADER structures.
-
- A useful constant defined in server.h is RECLEN. This should be used only
- as an array dimension for a stack character buffer, intended to be large
- enough to hold an arbitrary string. If you use this constant, you are
- making "large enough" the same value used in vn. Use it for fgets()
- buffers, or sprintf buffers prior to making allocated copies of the string,
- and you'll be working about the way vn does in a lot of places.
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'std.c'" '(24192 characters)'
- if test -f 'std.c'
- then
- echo shar: will not over-write existing file "'std.c'"
- else
- cat << \SHAR_EOF > 'std.c'
- #include <stdio.h>
- #include <pwd.h>
- #include <ctype.h>
- #include <sys/param.h>
- #include "server.h"
- #include "config_std.h"
- #include "std.h"
-
- #ifndef MAXPATHLEN
- #define MAXPATHLEN 240
- #endif
-
- extern NODE *hashfind();
- extern FILE *fopen();
- extern char *index(), *rindex();
- extern char *malloc();
- extern char *str_tstore(), *str_tpool(), *str_store();
- extern char *strtok(), *strpbrk();
- extern char *regex(), *regcmp();
-
- #ifdef MAILCHOOSE
- extern int (*Massage)();
- #endif
-
- /*
- global flags signifying options set
- */
- #define GF_ALL 1 /* -x option - scan everything */
- #define GF_SPEC 2 /* -n option(s) - user specified groups */
- #define GF_OVER 4 /* command line specification - overide marks */
-
- char *Vns_version = "res1.1";
-
- static char *Onews, *Newsrc;
- static int Ntopt, Nntopt, Nwopt, Nnwopt;
-
- static char *Wopt[NUMFILTER]; /* regular expressions for -w options */
- static char *Topt[NUMFILTER]; /* for -t options */
- static char *Negwopt[NUMFILTER]; /* for negated -w options */
- static char *Negtopt[NUMFILTER]; /* for negated -t options */
-
- static char *Options[OPTLINES];
- static int Max_name, Optlines;
- static unsigned Gflags = 0;
- static char **Active;
- static int Actnum;
- static char *Mailer, *Poster;
-
- static char *RT_head = RTHEAD;
- static char *P_head = PHEAD;
- static char *M_head = MHEAD;
- static char *R_head = RHEAD;
- static char *TO_head = TOHEAD;
- static char *F_head = FHEAD;
- static char *FT_head = FTHEAD;
- static char *T_head = THEAD;
- static char *DIS_head = DISHEAD;
- static char *L_head = LHEAD;
- static char *N_head = NHEAD;
-
- static char *Fpfix = FPFIX;
-
- /*
- ** environment setup.
- */
- vns_envir()
- {
- char dbuf[MAXPATHLEN], *rcname;
- char *vn_env();
- struct passwd *ptr, *getpwuid();
- #ifdef MAILCHOOSE
- int mail_prompt();
-
- Massage = mail_prompt;
- #endif
-
- ptr = getpwuid (getuid());
-
- rcname = vn_env("MAILER",DEF_MAIL);
- #ifdef INLETTER
- sprintf(dbuf,"cat %%s | %s",rcname);
- #else
- /* used as a format string TWICE (%%%% -> %% -> %) */
- sprintf(dbuf,"cat %%%%s | %s %%s",rcname);
- #endif
- Mailer = str_store(dbuf);
- rcname = vn_env("VNPOSTER",DEF_POST);
- sprintf(dbuf,"%s %%s",rcname);
- Poster = str_store(dbuf);
- rcname = vn_env("NEWSRC",DEF_NEWSRC);
- if (*rcname != '/')
- {
- sprintf (dbuf, "%s/%s",ptr->pw_dir,rcname);
- Newsrc = str_store (dbuf);
- }
- else
- Newsrc = str_store (rcname);
-
- /* above logic guarantees that Newsrc contains a '/' */
- strcpy(dbuf,Newsrc);
- strcpy(rindex(dbuf,'/')+1,".vnXXXXXX");
- mktemp(dbuf);
- Onews = str_store (dbuf);
-
- if (access (Newsrc,0) != 0)
- creat (Newsrc,0666);
- }
-
- /*
- change directory to group
- */
- vns_gset(grp)
- char *grp;
- {
- char dbuf [RECLEN];
- g_dir (grp,dbuf);
- if (chdir(dbuf) < 0)
- printex("can't change to newsgroup directory");
- }
-
- /*
- g_dir converts newsgroup name to directory string
- */
- static
- g_dir(s,t)
- char *s,*t;
- {
- char *ptr;
- sprintf (t,"%s/%s",SPOOLDIR,s);
- for (ptr=t+strlen(SPOOLDIR)+1; (ptr = index(ptr,'.')) != NULL; *ptr = '/')
- ;
- }
-
- /*
- ** myfind is used for hashfind() calls which aren't supposed to fail.
- */
- static NODE *
- myfind(name)
- char *name;
- {
- NODE *n;
-
- n = hashfind(name);
- if (n == NULL)
- printex("Unexpected table lookup failure");
- return (n);
- }
-
- vns_news(argc,argv,lfirst,nun)
- int argc;
- char **argv;
- int *lfirst, *nun;
- {
- FILE *fp;
- static char marks[] =
- {
- NEWS_ON, NEWS_OFF, '\0'
- };
- int line, len, num;
- char buf [RECLEN], trail, optpflag, submark, *fret, *ptr;
-
- ++argv;
- --argc;
-
- /* fill table with active newsgroups */
- fill_active ();
-
- if (argc > 0)
- {
- Gflags |= GF_OVER;
- arg_opt(argc,argv,lfirst,nun);
- optpflag = 'y';
- }
- else
- optpflag = 'n';
-
- if ((fp = fopen (Newsrc,"r")) == NULL)
- printex ("can't open %s for reading",Newsrc);
-
- Optlines = 0;
-
- for (line = 1; (fret = fgets(buf,RECLEN-1,fp)) != NULL && emptyline(buf) == 1; ++line)
- ;
- if (fret != NULL && strncmp (buf,"options",7) == 0)
- {
- Options[0] = str_store(buf);
- Optlines = 1;
- trail = buf [strlen(buf)-2];
- for ( ; (fret = fgets(buf,RECLEN-1,fp)) != NULL; ++line)
- {
- if (trail != '\\' && buf[0] != ' ' && buf[0] != '\t')
- break;
- if (Optlines >= OPTLINES)
- printex ("%s - too many option lines (%d allowed)",Newsrc,OPTLINES);
- Options[Optlines] = str_store(buf);
- ++Optlines;
- if ((len = strlen(buf)) >= 2 && buf[len-2] != '\\')
- trail = buf[len-2];
- else
- trail = '\0';
- }
- }
-
- /* do the options from the newsrc file if there weren't command line args */
- if (Optlines > 0 && optpflag == 'n')
- newsrc_opt (lfirst,nun);
-
- for ( ; fret != NULL; ++line, fret = fgets(buf,RECLEN-1,fp))
- {
- if (emptyline(buf) == 1)
- continue;
- if ((ptr = strpbrk(buf,marks)) == NULL)
- {
- fprintf (stderr,"\nwarning: line %d of %s (%s) - bad syntax\n",
- line,Newsrc,buf);
- continue;
- }
- submark = *ptr;
- *ptr = '\0';
- ++ptr;
- num = 0;
- for (ptr = strtok(ptr," ,-\n"); ptr != NULL; ptr = strtok(NULL," ,-\n"))
- {
- len = atoi (ptr);
- for ( ; *ptr >= '0' && *ptr <= '9'; ++ptr)
- ;
- if (*ptr != '\0' || len < num)
- {
- num = -1;
- fprintf (stderr,"\nwarning: line %d of %s (%s) - bad syntax\n",
- line,Newsrc,buf);
- break;
- }
- num = len;
- }
- if (num < 0)
- continue;
- chkgroup (buf,submark,num,0);
- }
- fclose (fp);
-
- /* now take care of groups not specified in .newsrc */
- art_active();
-
- /* free up the option string storage */
- for (num=0; num < Ntopt; ++num)
- regfree (Topt[num]);
- for (num=0; num < Nwopt; ++num)
- regfree (Wopt[num]);
- for (num=0; num < Nntopt; ++num)
- regfree (Negtopt[num]);
- for (num=0; num < Nnwopt; ++num)
- regfree (Negwopt[num]);
- Ntopt = Nwopt = Nntopt = Nnwopt = 0;
-
- /* free the active list */
- free ((char *) Active);
- }
-
- static
- emptyline(s)
- char *s;
- {
- while (isspace(*s))
- ++s;
- if (*s == '\0')
- return (1);
- return (0);
- }
-
- /*
- fill hash table from active news group list
- This is needed to be able to process options
- before scanning user order. Constructs an array
- of active newsgroup names for the rest of vns_nws().
- */
- static
- fill_active ()
- {
- FILE *f;
- char *nread, act_rec[RECLEN];
- int num,lownum,rcount;
-
- Max_name = 0;
- if ((f = fopen (ACTFILE,"r")) == NULL)
- printex ("couldn't open %s\n",ACTFILE);
-
- /*
- ** we do things this way so that we only examine active records
- ** once, minimizing the window where changes could screw us up
- ** at the cost of possibly alloc'ing a few extra bytes. We start
- ** with a count of one to have a positive rcount for alloc.
- */
- for(rcount=1; fgets(act_rec, RECLEN-1, f) != NULL; ++rcount)
- ;
- if ((Active = (char **) malloc(rcount*sizeof(char *))) == NULL)
- printex("Memory allocation failure");
-
- rewind(f);
-
- Actnum = 0;
- while (Actnum < rcount && fgets(act_rec, RECLEN-1, f) != NULL)
- {
- if (strtok (act_rec," \n") == NULL)
- continue;
- nread = strtok (NULL, " \n");
- if (nread != NULL)
- num = atoi(nread);
- else
- num = 0;
- nread = strtok (NULL, " \n");
- if (nread != NULL)
- lownum = atoi(nread);
- else
- lownum = 0;
- if (lownum > 0)
- --lownum;
- if (strlen(act_rec) > Max_name)
- Max_name = strlen(act_rec);
-
- /* enter newsgroup, point to permanent copy of name */
- hashenter (act_rec, num, lownum);
- Active[Actnum] = (myfind(act_rec))->nd_name;
- ++Actnum;
- }
-
- fclose (f);
- }
-
- /*
- check active newsgroups not mentioned in NEWSRC file
- (SFLG_SCAN not set)
- */
- static
- art_active ()
- {
- int i;
- NODE *ptr;
-
- for( i=0; i < Actnum; ++i)
- {
- ptr = myfind(Active[i]);
- if ((ptr->state & SFLG_SCAN) == 0)
- chkgroup (ptr->nd_name, NEWS_ON, 0, 1);
- }
- }
-
- /*
- check group for new articles:
- s - group
- c - subscription indicator from NEWSRC
- n - number read
- new - new newsgroup flag
- */
- static
- chkgroup (s,c,n,new)
- char *s,c;
- int n;
- int new;
- {
- NODE *ptr;
- char sub;
- int nrd;
- int lowart;
- int st;
-
- if ((ptr = hashfind(s)) != NULL && (ptr->state & SFLG_SCAN) == 0)
- {
- ptr->state |= SFLG_SCAN;
-
- #ifdef SYN_CHECK
- /* if "read" more than exist, reset */
- if (n > ptr->highnum)
- {
- n = ptr->highnum - SYN_SETBACK;
- fgprintf("%s: .newsrc out of synch, resetting\n",s);
- }
- #endif
- lowart = ptr->lownum;
- if (n < ptr->lownum)
- n = ptr->lownum;
-
- nrd = n;
- sub = c;
-
- /*
- ** scan decision is rather complex, since GF_ALL setting
- ** overides "n" value, GF_SPEC indicates SFLG_SPEC flag used.
- ** if GF_OVER set, SFLG_SPEC overides subscription mark, else
- ** SFLG_SPEC AND subscribed is neccesary.
- */
- if ((Gflags & GF_SPEC) != 0)
- {
- if ((ptr->state & SFLG_SPEC) == 0)
- c = NEWS_OFF;
- else
- {
- if ((Gflags & GF_OVER) != 0)
- c = NEWS_ON;
- }
- }
- if ((Gflags & GF_ALL) != 0)
- n = lowart;
- fw_group(s, new, sub == NEWS_ON, nrd, c == NEWS_ON);
- if (c == NEWS_ON && ptr->highnum > n)
- {
- st = outgroup (s,n,ptr->highnum);
- if (st > nrd)
- fw_chg(new, sub == NEWS_ON, st, c == NEWS_ON);
- }
- }
- }
-
- /*
- vns_write writes the .newsrc file
- */
- vns_write(news,ncount)
- NODE **news;
- int ncount;
- {
- FILE *fp;
- NODE *p;
- char c;
- int i,rc;
-
- if (link(Newsrc,Onews) < 0)
- printex ("can't backup %s to %s before writing",Newsrc,Onews);
-
- if (unlink(Newsrc) < 0 || (fp = fopen(Newsrc,"w")) == NULL)
- printex ("can't open %s for writing (backed up in %s)",Newsrc,Onews);
- else
- {
- clearerr(fp);
- for (i=0; (rc = ferror(fp)) == 0 && i < Optlines; ++i)
- fprintf (fp,"%s",Options[i]);
- for (i=0; rc == 0 && i < ncount; ++i)
- {
- p = news[i];
- if ((p->flags & FLG_SUB) == 0)
- c = NEWS_OFF;
- else
- c = NEWS_ON;
- #ifdef OLDRC
- fprintf (fp,"%s%c %d\n",p->nd_name,c,p->rdnum);
- #else
- if (p->rdnum > 0)
- fprintf(fp,"%s%c 1-%d\n",p->nd_name,c,p->rdnum);
- else
- fprintf(fp,"%s%c 0\n",p->nd_name,c);
- #endif
- rc = ferror(fp);
- }
- fclose (fp);
- if (rc != 0)
- printex ("write of %s failed, old copy stored in %s",Newsrc,Onews);
- else
- unlink (Onews);
- }
- }
-
- /*
- arg_opt must be called prior to option scanning, since
- it uses the options array. This is a bit of a kludge,
- but it saves a bunch of work. NOTE - no command name argument
- */
- static
- arg_opt (argc,argv,lfirst,nun)
- int argc;
- char **argv;
- int *lfirst, *nun;
- {
- if (argc > OPTLINES)
- printex ("too many command line options (%d allowed)\n",OPTLINES);
- for (Optlines=0; Optlines < argc; ++Optlines)
- {
- Options[Optlines] = *argv;
- ++argv;
- }
- newsrc_opt(lfirst,nun);
- }
-
- /*
- option setting routine:
- sets global flags: GF_ALL for -x option GF_SPEC for -n.
- sets up filter array for article scanning
- */
- static
- newsrc_opt(lfirst,nun)
- int *lfirst, *nun;
- {
- int i;
- char curopt,tmp[RECLEN],*tok;
-
- *nun = *lfirst = 0;
- Ntopt = Nwopt = Nnwopt = Nntopt = 0;
- curopt = '\0';
- for (i=0; i < Optlines; ++i)
- {
- strcpy(tmp,Options[i]);
- for (tok = strtok(tmp,",\\ \t\n"); tok != NULL; tok = strtok(NULL,",\\ \t\n"))
- {
- if (*tok != '-')
- do_opt (curopt,tok);
- else
- {
- for (++tok; index("nwt",*tok) == NULL; ++tok)
- {
- /* options with no strings */
- switch(*tok)
- {
- case 'S':
- Gflags &= ~GF_OVER;
- break;
- case '%':
- *lfirst = 1;
- break;
- case 'U':
- *nun = 1;
- break;
- #ifdef OLDRC
- case 'i':
- /* Treat "-i" as synonym for "-x" */
- #endif
- case 'x':
- Gflags |= GF_ALL;
- default:
- break;
- }
- }
- curopt = *tok;
- if (*(++tok) != '\0')
- do_opt (curopt,tok);
- }
- }
- }
- }
-
- /* do_opt is for options with strings attached */
- static
- do_opt (opt,str)
- char opt, *str;
- {
- switch (opt)
- {
- case 'n':
- Gflags |= GF_SPEC;
- specmark(str);
- break;
- case 'w':
- specfilter (FIL_AUTHOR,str);
- break;
- case 't':
- specfilter (FIL_TITLE,str);
- break;
- default:
- #ifdef OLDRC
- Gflags |= GF_SPEC; /* Assume anything else is newsgroup */
- specmark(str);
- #endif
- break;
- }
- }
-
- static
- specfilter (comp,str)
- char comp,*str;
- {
- int *count;
- char **rex;
-
- /*
- ** we may set rex one past end of array. we will error before
- ** referencing it if that's the case, however.
- */
- if (*str == '!')
- {
- if (comp == FIL_TITLE)
- {
- count = &Nntopt;
- rex = Negtopt + *count;
- }
- else
- {
- count = &Nnwopt;
- rex = Negwopt + *count;
- }
- ++str;
- }
- else
- {
- if (comp == FIL_TITLE)
- {
- count = &Ntopt;
- rex = Topt + *count;
- }
- else
- {
- count = &Nwopt;
- rex = Wopt + *count;
- }
- }
- if (*count >= NUMFILTER)
- printex ("too many %c options, %d allowed",comp,NUMFILTER);
- if ((*rex = regcmp(str,(char *) 0)) == NULL)
- printex ("%c option regular expression syntax: %s",comp,str);
- ++(*count);
- }
-
- /*
- handle the newsgroup specification string.
- ("all" convention - braack!!!)
- */
- static
- specmark (s)
- char *s;
- {
- unsigned ormask,andmask;
- int i,len;
- char *ptr,*re,pattern[RECLEN];
- NODE *nptr;
-
- if (*s == '!')
- {
- ++s;
- ormask = 0;
- andmask = ~SFLG_SPEC;
- if (*s == '\0')
- return;
- }
- else
- {
- ormask = SFLG_SPEC;
- andmask = 0xffff;
- }
-
- /* convert "all" not bounded by alphanumerics to ".*". ".all" becomes ".*" */
- for (ptr = s; (len = findall(ptr)) >= 0; ptr += len+1)
- {
- if (len > 0 && isalnum (s[len-1]))
- continue;
- if (isalnum (s[len+3]))
- continue;
- if (len > 0 && s[len-1] == '.')
- {
- --len;
- strcpy (s+len,s+len+1);
- }
- s[len] = '.';
- s[len+1] = '*';
- strcpy (s+len+2,s+len+3);
- }
-
- /* now use regular expressions */
- sprintf (pattern,"^%s$",s);
- if ((re = regcmp(pattern,(char *) 0)) == NULL)
- printex ("n option regular expression syntax: %s",s);
- for (i=0; i < Actnum; ++i)
- {
- nptr = myfind(Active[i]);
- if (regex(re,nptr->nd_name) != NULL)
- {
- nptr->state |= ormask;
- nptr->state &= andmask;
- }
- }
- regfree (re);
- }
-
- static
- findall (s)
- char *s;
- {
- int len;
- for (len=0; *s != '\0'; ++s,++len)
- {
- if (*s == 'a' && strncmp(s,"all",3) == 0)
- return (len);
- }
- return (-1);
- }
-
- static
- grp_indic (s,ok)
- char *s;
- int ok;
- {
- if (ok)
- fgprintf(" %s\n",s);
- else
- fgprintf(" %s - Can't access spool directory\n",s);
- }
-
- /*
- enter newsgroup articles.
- all articles between low and hi are to be included.
-
- Returns the highest number less than an OPENED (not neccesarily
- accepted) article to allow caller to revise "articles read"
- number beyond non-existent articles.
- */
- outgroup (s,low,hi)
- char *s;
- int low,hi;
- {
- int i;
- char subj[RECLEN], lines[RECLEN], auth[RECLEN], gd[RECLEN];
- int ret,op;
-
- if ((hi-low) > MAXARTRANGE)
- low = hi - MAXARTRANGE;
-
- ret = low;
- op = 1;
-
- g_dir(s,gd);
- if (chdir(gd) < 0)
- {
- grp_indic(s,0);
- return (ret);
- }
- grp_indic(s,1);
- for (i=low+1; i <= hi; ++i)
- {
- if (digname(i,subj,lines,auth,&op) >= 0)
- {
- fw_art(i,subj,lines,auth);
- }
- else
- {
- if (op)
- ret = i;
- }
- }
-
- return(ret);
- }
-
- /*
- ** open article and interpret options, if any. The op parameter is set
- ** to ZERO if and only if an article is opened. Used above as a flag to
- ** indicate no articles opened yet.
- */
- static digname (n, subj, lines, auth, op)
- int n;
- char *subj, *lines, *auth;
- int *op;
- {
- int i,j;
- FILE *fp;
- char t[RECLEN];
- char *nfgets();
-
- /* open article */
- sprintf (t,"%d", n);
- if ((fp = fopen(t,"r")) == NULL)
- return (-1);
- *op = 0;
-
- /* get subject, from and lines by reading article */
- subj[0] = lines[0] = auth[0] = '?';
- subj[1] = lines[1] = auth[1] = '\0';
- for (i = 0; i < HDR_LINES && nfgets(t,RECLEN-1,fp) != NULL; ++i)
- {
- if (index(CHFIRST,t[0]) == NULL)
- continue;
- t[strlen(t) - 1] = '\0';
- if (strncmp(T_head,t,THDLEN) == 0)
- {
- for (j=0; j < Nntopt; ++j)
- {
- if (regex(Negtopt[j],t+THDLEN) != NULL)
- {
- fclose(fp);
- return(-1);
- }
- }
- if (Ntopt > 0)
- {
- for (j=0; j < Ntopt; ++j)
- {
- if (regex(Topt[j],t+THDLEN) != NULL)
- break;
- }
- if (j >= Ntopt)
- {
- fclose(fp);
- return(-1);
- }
- }
- strcpy(subj,t+THDLEN);
- continue;
- }
- if (strncmp(F_head,t,FHDLEN) == 0)
- {
- for (j=0; j < Nnwopt; ++j)
- {
- if (regex(Negwopt[j],t+FHDLEN) != NULL)
- {
- fclose(fp);
- return(-1);
- }
- }
- if (Nwopt > 0)
- {
- for (j=0; j < Nwopt; ++j)
- {
- if (regex(Wopt[j],t+FHDLEN) != NULL)
- break;
- }
- if (j >= Nwopt)
- {
- fclose(fp);
- return(-1);
- }
- }
- strcpy(auth,t+FHDLEN);
- continue;
- }
- if (strncmp(L_head,t,LHDLEN) == 0)
- {
- strcpy(lines,t+LHDLEN);
- break;
- }
- }
-
- fclose (fp);
-
- /* reject empty or 1 line files */
- if (i < 2)
- return (-1);
-
- return (0);
- }
-
- /*
- ** special fgets for reading header lines, which unfolds continued lines
- ** and throws away trailing stuff on buffer overflow.
- */
- static char *
- nfgets(buf, size, fp)
- char *buf;
- int size;
- FILE *fp;
- {
- register int c;
-
- while (!feof(fp))
- {
- if ((c = getc(fp)) == '\n')
- {
- if ((c = getc(fp)) == '\t' || c == ' ')
- continue;
- ungetc(c, fp);
- *buf = '\n';
- ++buf;
- *buf = '\0';
- ++buf;
- return (buf);
- }
-
- /* prevent "terminal bombs" */
- if (c < ' ' || c == '\177')
- {
- switch(c)
- {
- case '\r':
- case '\010':
- case '\07':
- break;
- case '\177':
- c = '~';
- break;
- case '\t':
- c = ' ';
- break;
- default:
- if (size > 1)
- {
- *buf = '^';
- ++buf;
- --size;
- }
- c += 'A' - 1;
- break;
- }
- }
-
- if (size > 0)
- {
- *buf = c;
- ++buf;
- --size;
- }
- if (c == '\r')
- {
- if ((c = getc(fp)) != '\n')
- {
- ungetc(c, fp);
- continue;
- }
- if ((c = getc(fp)) != ' ' && c != '\t')
- {
- *buf = '\0';
- ++buf;
- ungetc(c, fp);
- return (buf);
- }
- --buf;
- ++size;
- continue;
- }
- }
-
- *buf = '\0';
- ++buf;
- return (NULL);
- }
-
- static char *Mail[2], *Show[6], *Post[4];
- static char *Priv[8];
- static char *Pool = NULL;
-
- FILE *
- vns_aopen(art,hdr)
- int art;
- ARTHEADER *hdr;
- {
- char buf[RECLEN];
- char *dist, *reply, *from, *ngrp, *flto, *path, *resubj;
- FILE *fp;
- int n;
- char *mail_trim();
-
- dist = resubj = path = reply = from = ngrp = flto = NULL;
-
- sprintf(buf,"%d",art);
- if ((fp = fopen(buf,"r")) == NULL)
- return(NULL);
-
- /*
- ** we only really need a lot extra if MAILCHOOSE, but allocating
- ** a temporary array of pointers isn't that much. Similarly, a
- ** few assignments, and the "Priv" declaration are only needed
- ** with some define settings. Not worth ifdef'ing.
- */
- Pool = str_tpool(100);
-
- hdr->artid = "<some article>";
- hdr->from = "<somebody>";
- hdr->priv = Priv;
- hdr->postcmd = Poster;
- hdr->mail = Mail;
- hdr->show = Show;
- hdr->post = Post;
- hdr->priv_num = hdr->show_num = hdr->post_num = hdr->mail_num = 0;
-
- /* for conditional is abnormal - expected exit is break */
- for (n=0; n < HDR_LINES && fgets(buf,RECLEN-1,fp) != NULL; ++n)
- {
- /* bail out at first non-header line */
- if (buf[0] == '\n')
- break;
- if (strncmp(buf,RT_head,RTHDLEN) == 0)
- {
- buf [strlen(buf)-1] = '\0';
- reply = str_tstore(Pool,buf+RTHDLEN);
- continue;
- }
- if (strncmp(buf,P_head,PHDLEN) == 0)
- {
- buf [strlen(buf)-1] = '\0';
- path = str_tstore(Pool,buf+PHDLEN);
- continue;
- }
- if (strncmp(buf,DIS_head,DISHDLEN) == 0)
- {
- buf [strlen(buf)-1] = '\0';
- dist = str_tstore(Pool,buf);
- continue;
- }
- if (strncmp(buf,M_head,MHDLEN) == 0)
- {
- buf [strlen(buf)-1] = '\0';
- hdr->artid = str_tstore(Pool,buf+MHDLEN);
- continue;
- }
- if (strncmp(buf,F_head,FHDLEN) == 0)
- {
- buf [strlen(buf)-1] = '\0';
- (hdr->show)[hdr->show_num] = str_tstore(Pool,buf);
- from = hdr->from = (hdr->show)[hdr->show_num]+FHDLEN;
- ++(hdr->show_num);
- continue;
- }
- if (strncmp(buf,T_head,THDLEN) == 0)
- {
- buf [strlen(buf)-1] = '\0';
- (hdr->show)[hdr->show_num] = str_tstore(Pool,buf);
- if (strncmp(buf+THDLEN,Fpfix,FPFLEN) != 0)
- {
- sprintf(buf,"%s%s%s",T_head,Fpfix,
- ((hdr->show)[hdr->show_num])+THDLEN);
- resubj = str_tstore(Pool,buf);
- }
- else
- resubj = (hdr->show)[hdr->show_num];
- ++(hdr->show_num);
- continue;
- }
- if (strncmp(buf,N_head,NHDLEN) == 0)
- {
- buf [strlen(buf)-1] = '\0';
-
- /* if multiple newsgroups, include in "show" */
- if (index(buf,',') != NULL)
- {
- (hdr->show)[hdr->show_num] = str_tstore(Pool,buf);
- ngrp = (hdr->show)[hdr->show_num] + NHDLEN;
- ++(hdr->show_num);
- }
- else
- ngrp = str_tstore(Pool,buf+NHDLEN);
- continue;
- }
- if (strncmp(buf,FT_head,FTHDLEN) == 0)
- {
- buf [strlen(buf)-1] = '\0';
- (hdr->show)[hdr->show_num] = str_tstore(Pool,buf);
- flto = (hdr->show)[hdr->show_num] + FTHDLEN;
- ++(hdr->show_num);
- continue;
- }
- if (strncmp(buf,L_head,LHDLEN) == 0)
- {
- buf [strlen(buf)-1] = '\0';
- hdr->lines = atoi(buf+LHDLEN);
- (hdr->show)[hdr->show_num] = str_tstore(Pool,buf);
- ++(hdr->show_num);
- continue;
- }
- }
-
- hdr->hlines = n;
-
- #ifdef MAILCHOOSE
- (hdr->priv)[hdr->priv_num] = resubj;
- ++(hdr->priv_num);
- if (reply != NULL)
- {
- (hdr->priv)[hdr->priv_num] = mail_trim(reply);
- ++(hdr->priv_num);
- }
- if (from != NULL)
- {
- (hdr->priv)[hdr->priv_num] = mail_trim(from);
- ++(hdr->priv_num);
- }
- if (path != NULL)
- {
- (hdr->priv)[hdr->priv_num] = mail_trim(path);
- ++(hdr->priv_num);
- }
- #else
- #ifdef MAILSMART
- if (reply == NULL)
- if (from != NULL)
- reply = from;
- else
- {
- if (path != NULL)
- reply = path;
- }
- #else
- if (path != NULL)
- reply = path;
- #endif
- if (reply != NULL)
- reply = mail_trim(reply);
- mail_cmd(hdr,reply,resubj);
- #endif /* MAILCHOOSE */
-
- if (flto == NULL)
- {
- if ((flto = ngrp) == NULL)
- flto = "group.unknown";
- }
- ngrp = rindex(flto,'.');
-
- if (strncmp("mod.",flto,4) == 0 ||
- (ngrp != NULL && strcmp(".announce",ngrp) == 0))
- {
- sprintf(buf,"Cannot post a follow-up to \"%s\", reply with mail to moderator",flto);
- hdr->post_err = str_tstore(Pool,buf);
- return (fp);
- }
-
- if (ngrp != NULL && strcmp(ngrp,".general") == 0)
- {
- *ngrp = '\0';
- sprintf(buf,"%s%s.followup",N_head,flto);
- }
- else
- sprintf(buf,"%s%s",N_head,flto);
- flto = str_tstore(Pool,buf);
-
- hdr->post_err = NULL;
-
- if (resubj != NULL)
- {
- (hdr->post)[hdr->post_num] = resubj;
- ++(hdr->post_num);
- }
-
- (hdr->post)[hdr->post_num] = flto;
- ++(hdr->post_num);
-
- sprintf(buf,"%s%s",R_head,hdr->artid);
- (hdr->post)[hdr->post_num] = str_tstore(Pool,buf);
- ++(hdr->post_num);
-
- if (dist != NULL)
- {
- (hdr->post)[hdr->post_num] = dist;
- ++(hdr->post_num);
- }
-
- return (fp);
- }
-
- #ifdef MAILCHOOSE
- /*
- ** routine to prompt user for mail path approval
- */
- static
- mail_prompt(hdr)
- ARTHEADER *hdr;
- {
- int i;
- char buf[RECLEN],*ptr;
-
- tty_set(SAVEMODE);
- for (i=1; i < hdr->priv_num; ++i)
- {
- printf("%d - %s\n",i,(hdr->priv)[i]);
- }
- printf("\nType number to choose one of the above, or input address: ");
- fgets(buf,RECLEN-1,stdin);
- tty_set(RESTORE);
-
- ptr = strtok(buf," \t\n");
- if (ptr == NULL)
- ptr = "";
-
- i = strlen(ptr);
- if (i == 1)
- {
- i = atoi(ptr);
- if (i > 0 && i <= hdr->priv_num)
- ptr = (hdr->priv)[i];
- i = 1;
- }
-
- /*
- ** If the user keeps cycling through here on the same article,
- ** we will eventually run out of strings. We made Pool large
- ** enough to make it unlikely (user will have to retry about 80
- ** times without switching articles). Hardly elegant, but should
- ** be sufficient.
- */
- if (i > 1 && hdr->priv_num < 8)
- {
- (hdr->priv)[hdr->priv_num] = str_tstore(Pool,ptr);
- ++(hdr->priv_num);
- }
- mail_cmd(hdr,ptr,(hdr->priv)[0]);
- }
- #endif
-
- /*
- ** trim () off potential mail address, and make copy if needed.
- ** addr must be allocated string.
- */
- static char *
- mail_trim(addr)
- char *addr;
- {
- char buf[RECLEN];
- char *ptr;
-
- if (index(addr,'(') == NULL)
- return(addr);
-
- strcpy(buf,addr);
- ptr = index(buf,'(');
- for (--ptr; *ptr == ' ' || *ptr == '\t'; --ptr)
- ;
- ++ptr;
- *ptr = '\0';
- return (str_tstore(Pool,buf));
- }
-
- /*
- ** format mail command. Subj must point to allocated string.
- */
- static
- mail_cmd(hdr,addr,subj)
- ARTHEADER *hdr;
- char *addr, *subj;
- {
- char buf[RECLEN];
-
- if (addr == NULL || *addr == '\0')
- {
- hdr->mail_err = "No address";
- return;
- }
-
- hdr->mail_err = NULL;
- ;
-
- #ifdef INLETTER
- hdr->mailcmd = Mailer;
- sprintf(buf,"%s%s",TO_head,addr);
- (hdr->mail)[0] = str_tstore(Pool,buf);
- hdr->mail_num = 1;
- #else
- sprintf(buf,Mailer,addr);
- hdr->mailcmd = str_tstore(Pool,buf);
- hdr->mail_num = 0;
- #endif
- if (subj != NULL)
- {
- (hdr->mail)[hdr->mail_num] = subj;
- ++(hdr->mail_num);
- }
- }
-
- vns_aclose(fp)
- FILE *fp;
- {
- if (Pool != NULL)
- str_tfree(Pool);
- Pool = NULL;
- fclose(fp);
- }
-
- /*
- ** we don't use the count / name / mode arguments because this doesn't
- ** implement any fancy article massaging
- */
- vns_asave(art,fp)
- int art;
- FILE *fp;
- {
- char buf[RECLEN];
- FILE *fin;
-
- sprintf(buf,"%d",art);
- if ((fin = fopen(buf,"r")) == NULL)
- return;
-
- while (fgets(buf,RECLEN-1,fin) != NULL)
- fputs(buf,fp);
- fclose(fin);
- }
-
- vns_exit()
- {
- }
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'std.h'" '(886 characters)'
- if test -f 'std.h'
- then
- echo shar: will not over-write existing file "'std.h'"
- else
- cat << \SHAR_EOF > 'std.h'
- /*
- newsrc states
- */
- #define NEWS_ON ':'
- #define NEWS_OFF '!'
-
- #define SFLG_SCAN 1
- #define SFLG_SPEC 2
-
- #define FPFIX "Re: "
- #define FPFLEN 4
-
- #define FIL_AUTHOR 'w'
- #define FIL_TITLE 't'
-
- /*
- header lines and associated lengths. Strings should
- actually be used only once.
- */
- #define RHEAD "References: "
- #define RHDLEN 12
- #define MHEAD "Message-ID: "
- #define MHDLEN 12
- #define PHEAD "Path: "
- #define PHDLEN 6
- #define DHEAD "Date: "
- #define DHDLEN 6
- #define RTHEAD "Reply-To: "
- #define RTHDLEN 10
- #define TOHEAD "To: "
- #define TOHDLEN 4
- #define FHEAD "From: "
- #define FHDLEN 6
- #define FTHEAD "Followup-To: "
- #define FTHDLEN 13
- #define DISHEAD "Distribution: "
- #define DISHDLEN 14
- #define THEAD "Subject: "
- #define THDLEN 9
- #define LHEAD "Lines: "
- #define LHDLEN 7
- #define NHEAD "Newsgroups: "
- #define NHDLEN 12
-
- #define CHFIRST "FSL" /* first char's of those used in page display */
- SHAR_EOF
- fi # end of overwriting check
- echo shar: extracting "'config_std.h'" '(2824 characters)'
- if test -f 'config_std.h'
- then
- echo shar: will not over-write existing file "'config_std.h'"
- else
- cat << \SHAR_EOF > 'config_std.h'
- /*
- ** default news poster
- */
- #define DEF_POST "/usr/lib/news/inews -h"
-
- /*
- ** default user .newsrc file
- */
- #define DEF_NEWSRC ".newsrc"
-
- /*
- ** If INLETTER is defined, the address line will be placed into the
- ** file editted by the user, and the mailer is assumed smart enough
- ** to understand about header lines in the file. Otherwise the
- ** address is part of the mailer's command line.
- **
- ** if MAILSMART is defined, The From: line will be used for mail replies,
- ** or overridden by a "Reply-to:" line if present - "Path:" will be used
- ** as a last resort. If MAILSMART is not defined, "Path:" will simply be
- ** used.
- **
- ** if MAILCHOOSE is defined, the user is prompted before edit with all
- ** of the address lines to choose from, or to input a new one. MAILCHOOSE
- ** makes MAILSMART irrelevant, but the two are independent of INLETTER.
- **
- #define MAILCHOOSE
- */
- #define MAILSMART
- #define INLETTER
-
- /*
- ** default mail sender. If INLETTER, will be done as
- ** cat <file> | DEF_MAIL, Otherwise, cat <file> | DEF_MAIL <address>
- ** user's MAILER variable will have to conform, too.
- */
- #ifdef INLETTER
- #define DEF_MAIL "/usr/lib/sendmail -t"
- #else
- #define DEF_MAIL "/bin/mail"
- #endif
- ** OLDRC defined for an apparently earlier news version which took unnamed
- ** command line options as synonyms for -n, and did not take ranges in
- ** the .newsrc file. Probably useless, but kept in for historical reasons.
- **
- **#define OLDRC
- */
-
- /*
- ** article spool directory
- */
- #define SPOOLDIR "/usr/spool/news"
-
- /*
- ** active file
- */
- #define ACTFILE "/usr/lib/news/active"
-
- /*
- ** maximum number of option lines in .newsrc
- */
- #define OPTLINES 60
-
- /*
- ** maximum number of filter options
- */
- #define NUMFILTER 30
-
- /*
- ** maximum number of file lines to search looking for header lines.
- */
- #define HDR_LINES 36
-
- /*
- ** When a newsgroup is scanned, we ignore articles less than <high spool> -
- ** MAXARTRANGE. This is intended to prevent ridiculous numbers of article
- ** opening attempts the first time a user reads a new newsgroup which has a
- ** huge difference between the high and low spool numbers, perhaps due to
- ** some articles not getting expired.
- */
- #define MAXARTRANGE 1600 /* about 2 weeks of soc.singles */
-
- /*
- ** If we detect that the user has a higher number in .newsrc than the
- ** high article number, obviously the active file is out of synch with the
- ** .newsrc. We set the user's number back to the low article number in
- ** this case, on the theory that it's better to repeat stuff than miss
- ** articles. On such setbacks, we won't backdate the user by more than
- ** SYN_SETBACK articles, preventing floods of articles on large newsgroups
- ** if you don't define SYN_CHECK, the user's number won't be adjusted in
- ** this case, choosing to lose articles rather than show old ones.
- */
- #define SYN_CHECK
- #define SYN_SETBACK 60
- SHAR_EOF
- fi # end of overwriting check
- # End of shell archive
- exit 0
-